package com.spark.sniffer.plugin.plugins.interceptor;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Collection;

import com.spark.sniffer.AgentArgs;
import com.spark.sniffer.logging.api.Logger;
import com.spark.sniffer.logging.api.LoggerFactory;
import com.spark.sniffer.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import com.spark.sniffer.plugin.interceptor.enhance.MethodInterceptResult;
import com.spark.sniffer.tracing.Span;
import com.spark.sniffer.tracing.TracingContext;

public class RedisTemplateInterceptor implements InstanceMethodsAroundInterceptor {
    private static final Logger log = LoggerFactory.getLogger(RedisTemplateInterceptor.class);

    @Override
    public void beforeMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        MethodInterceptResult result) throws Throwable {
        String key = null;
        if (!AgentArgs.isSimpleTracing() && allArguments != null && allArguments.length > 0
            && allArguments[0] != null) {
            if (allArguments[0] instanceof String) {
                key = (String)allArguments[0];
            } else if (allArguments[0] instanceof Collection) {
                Collection keys = (Collection)allArguments[0];
                key = keys.size() + "-keys";
            } else if (allArguments[0].getClass().isArray()) {
                key = Array.getLength(allArguments[0]) + "-keys";
            } else {
                key = allArguments[0].toString();
            }
        }

        TracingContext.getContext().startSpan(Span.Type.Redis,
            method.getName() + (AgentArgs.isSimpleTracing() ? "" : ("<" + key + ">")));
    }

    @Override
    public Object afterMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        TracingContext.getContext().stopSpan();
        return ret;
    }

    @Override
    public void handleMethodException(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Throwable t) {
        TracingContext.getContext().setActiveSpanCode(Span.ERR_CODE);
    }
}
